package pl.vm.domain;

import java.util.logging.Logger;

import pl.vm.domain.exceptions.InvalidPlayerException;
import pl.vm.domain.exceptions.NotEnoughSpaceException;
import pl.vm.domain.exceptions.PlayerAlreadyExistException;
import pl.vm.domain.exceptions.PlayerNotExistsException;
import pl.vm.domain.exceptions.WrongPlayerPositionException;

/**
 * Squad of the Virtual Team
 * @author krzysztof.graczyk
 *
 */
public class Squad {

	private SquadComposition mainSquad;
	private SquadComposition reserveSquad;
	private Player coach;
	private static Logger logger = Logger.getLogger(Squad.class
			.getCanonicalName());

	public Squad() {
	}

	public Squad(SquadComposition main, SquadComposition reserve, Player coach) {
		super();
		this.mainSquad = main;
		this.reserveSquad = reserve;
		this.coach = coach;
	}

	public boolean validate() {
		if (coach == null) {
			return false;
		}
		try {
			assertCoach(coach);
		} catch (WrongPlayerPositionException e) {
			return false;
		} 
		return mainSquad.validate() && reserveSquad.validate();
	}
	
	public SquadComposition getMainSquad() {
		return mainSquad;
	}

	public SquadComposition getReserveSquad() {
		return reserveSquad;
	}

	public Player getCoach() {
		return coach;
	}

	public void setMainSquad(SquadComposition mainSquad) {
		this.mainSquad = mainSquad;
	}

	public void setReserveSquad(SquadComposition reserveSquad) {
		this.reserveSquad = reserveSquad;
	}

	public void setCoach(Player coach) throws WrongPlayerPositionException {
		this.coach = assertCoach(coach);
	}

	private Player assertCoach(Player coach) throws WrongPlayerPositionException {
		if (coach.getPosition() == PlayerPosition.COACH) {
			return coach;
		} else {
			throw new WrongPlayerPositionException("Player: " + coach + " is not"
					+ PlayerPosition.COACH);
		}
	}
	
	/**
	 * Adds a player to a squad. First the main squad is checked if there is
	 * free space for the player, then the reserve is checked.
	 * */
	public void addPlayer(Player player) throws NotEnoughSpaceException,
			PlayerAlreadyExistException {
		if (player.getPosition() == PlayerPosition.COACH) {
			if (this.coach != null) {
				throw new NotEnoughSpaceException("Coach is already set.");
			} else {
				this.coach = player;
				return;
			}
		}
		if (playerInSquad(player)) {
			throw new PlayerAlreadyExistException("Player: " + player + " is already set.");
		}
		try {
			mainSquad.addPlayer(player);
		} catch (NotEnoughSpaceException e) {
			try {
				reserveSquad.addPlayer(player);
			} catch (InvalidPlayerException e1) {
				logger.info(e.getLocalizedMessage());
			}
		} catch (InvalidPlayerException e) {
			logger.info(e.getLocalizedMessage());
		}
	}
	
	public boolean playerInSquad(Player player) {
		return mainSquad.exist(player) || reserveSquad.exist(player);
	}
	
	public void removePlayer(Player player) throws PlayerNotExistsException, InvalidPlayerException {
		if (player.getPosition() == PlayerPosition.COACH) {
			this.coach = null;
		}
		if (mainSquad.exist(player)) {
			mainSquad.removePlayer(player);
		} else if (reserveSquad.exist(player)) {
			reserveSquad.removePlayer(player);
		} else {
			throw new PlayerNotExistsException();
		}
	}

	public void switchPlayer(Player main, Player reserve) throws WrongPlayerPositionException, InvalidPlayerException, NotEnoughSpaceException, PlayerNotExistsException {
		if (main.getPosition() != reserve.getPosition()) {
			throw new WrongPlayerPositionException("Player: " + main + ", should play on the same position as " + reserve);
		}
		if (mainSquad.exist(main) && reserveSquad.exist(reserve)) {
			mainSquad.removePlayer(main);
			reserveSquad.removePlayer(reserve);
			mainSquad.addPlayer(reserve);
			reserveSquad.addPlayer(main);
		} else {
			throw new PlayerNotExistsException("Either main or reserve player not exist in squad");
		}
	}

	public void movePlayerToMain(Player reserve) throws NotEnoughSpaceException, InvalidPlayerException, PlayerNotExistsException {
		if (reserveSquad.exist(reserve)) {
			mainSquad.addPlayer(reserve);
			reserveSquad.removePlayer(reserve);
		} else {
			throw new PlayerNotExistsException("Player: " + reserve + ", does not exist in reserve squad");
		}
	}

	public void movePlayerToReserve(Player main) throws NotEnoughSpaceException, InvalidPlayerException, PlayerNotExistsException {
		if (mainSquad.exist(main)) {
			reserveSquad.addPlayer(main);
			mainSquad.removePlayer(main);
		} else {
			throw new PlayerNotExistsException("Player: " + main + ", does not exist in main squad");
		}
	}
}
